
#include "type.h"
#include "sim_timer_config.h"

#ifndef SIM_TIMER_MAX
#error "SIM_TIMER_MAX NOT HAVE A CONFIG VALUE"
#endif

#define count           0
#define timeout         1
#define running         2
#define overtime        3
#define offset_max      4

static volatile uint16_t SIM_TIMERS[SIM_TIMER_MAX*offset_max];

void sim_timer_init(void)
{
    volatile uint8_t i;
    for (i = 0; i < SIM_TIMER_MAX*offset_max; i++) {
        SIM_TIMERS[i] = 0;
    }
}

void sim_timer_tick_hander(void)
{
	volatile uint8_t i;
    volatile uint8_t j;
    for (i = 0; i < SIM_TIMER_MAX; i++) {
        j = i*offset_max;
        if ((SIM_TIMERS[j+running] == true)&&(SIM_TIMERS[j+overtime] == false)) {
            if(SIM_TIMERS[j+count] > 0){
                SIM_TIMERS[j+count]--;
            }
            else{
                SIM_TIMERS[j+count] = 0;
            }
            if (SIM_TIMERS[j+count] == 0) {
                SIM_TIMERS[j+count] = SIM_TIMERS[j+timeout];
                SIM_TIMERS[j+overtime] = true;
            }
        }
    }
}

bool_t sim_timer_check_running(uint8_t sim_timer_num)
{
    if(sim_timer_num < SIM_TIMER_MAX){
        sim_timer_num = sim_timer_num*offset_max;
        return SIM_TIMERS[sim_timer_num+running];
    }
    else{
        return false;
    }
}

bool_t sim_timer_check_overtime(uint8_t sim_timer_num)
{
    bool_t ret;
    if(sim_timer_num < SIM_TIMER_MAX){
        sim_timer_num = sim_timer_num*offset_max;
        ret =  SIM_TIMERS[sim_timer_num+overtime];
        SIM_TIMERS[sim_timer_num+overtime] = false;
        return ret;
    }
    else{
        return false;
    }
}

void sim_timer_start(uint8_t sim_timer_num)
{
    if(sim_timer_num < SIM_TIMER_MAX){
        sim_timer_num = sim_timer_num*offset_max;
        SIM_TIMERS[sim_timer_num+running] = true;
    }  
}

void sim_timer_stop(uint8_t sim_timer_num)
{
    if(sim_timer_num < SIM_TIMER_MAX){
        sim_timer_num = sim_timer_num*offset_max;
        SIM_TIMERS[sim_timer_num+running] = false;
    }  
}

void sim_timer_restart(uint8_t sim_timer_num)
{ 
    if(sim_timer_num < SIM_TIMER_MAX){
        sim_timer_num = sim_timer_num*offset_max;
        SIM_TIMERS[sim_timer_num+count] = SIM_TIMERS[sim_timer_num+timeout];
        SIM_TIMERS[sim_timer_num+running] = true;
    }
}

void sim_timer_set_timeout(uint8_t sim_timer_num, uint16_t set_timeout)
{
    if(sim_timer_num < SIM_TIMER_MAX){
        sim_timer_num = sim_timer_num*offset_max;
        SIM_TIMERS[sim_timer_num+timeout] = set_timeout;
    }
}
